/*
@Time : 2020/12/29 10:36 上午
@Author : chenle
@File : log
@Software: GoLand
*/
package lego

import (
	"fmt"
	"github.com/rs/zerolog"
	"io"
	"log"
	"os"
	"time"
)

// getLogFilePath get the log file save path
func getLogFilePath() string {
	return confValue.LogPath
	//return fmt.Sprintf("%s%s", confValue.GetConfig().RuntimeRootPath, conf.GetConfig().LogSavePath)
}

// getLogFileName get the save name of the log file
func getLogFileName() string {
	return fmt.Sprintf("%s%s.%s",
		"log-",
		time.Now().Format("2006-01-02"),
		"log",
	)
}

type Level int

var (
	F *os.File

	DefaultPrefix      = ""
	DefaultCallerDepth = 2

	//logger     *log.Logger
	logPrefix  = ""
	levelFlags = []string{"DEBUG", "INFO", "WARN", "ERROR", "FATAL"}
	sysLogger  zerolog.Logger
	logger     zerolog.Logger
)

const (
	DEBUG Level = iota
	INFO
	WARNING
	ERROR
	FATAL
)

//// Setup initialize the log instance
//func setup() {
//	var err error
//	filePath := getLogFilePath()
//	fileName := getLogFileName()
//	F, err = MustOpen(fileName, filePath)
//	if err != nil {
//		log.Fatalf("logging.Setup err: %v", err)
//	}
//
//	if app.Engine.Config.MultiLog {
//		Logger = log.New(io.MultiWriter(F, os.Stdout), DefaultPrefix, log.LstdFlags)
//	} else {
//		Logger = log.New(F, DefaultPrefix, log.LstdFlags)
//	}
//
//}

func Infof(format string, v ...interface{}) {
	logger.Info().Msgf(format, v...)
}

func Debugf(format string, v ...interface{}) {
	logger.Debug().Msgf(format, v...)
}

func Errorf(format string, v ...interface{}) {
	logger.Error().Msgf(format, v...)
}

func Fatalf(format string, v ...interface{}) {
	logger.Fatal().Msgf(format, v...)
}

func Info(v string) {
	logger.Info().Msg(v)
}

// Debug output logs at debug level
func Debug(v string) {
	logger.Debug().Msg(v)
}

//// Info output logs at info level
//func Info(v ...interface{}) {
//	setPrefix(INFO)
//	logger.Println(v...)
//
//}

//// Info output logs at info level
//func Infof(format string, v ...interface{}) {
//	setPrefix(INFO)
//	logger.Printf(format+"\n", v...)
//}

// Warn output logs at warn level
func Warn(v string) {
	logger.Warn().Msg(v)
}

// Error output logs at error level
func Error(v string) {
	logger.Error().Msg(v)
}

//// Error output logs at error level
//func Errorf(format string, v ...interface{}) {
//	setPrefix(ERROR)
//	logger.Printf(format+"\n", v...)
//}

// Fatal output logs at fatal level
func Fatal(v string) {
	logger.Fatal().Msg(v)
}

//// setPrefix set the prefix of the log output
//func setPrefix(level Level) {
//	_, file, line, ok := runtime.Caller(DefaultCallerDepth)
//	if ok {
//		logPrefix = fmt.Sprintf("[%s][%s:%d]", levelFlags[level], filepath.Base(file), line)
//	} else {
//		logPrefix = fmt.Sprintf("[%s]", levelFlags[level])
//	}
//
//	Logger.SetPrefix(logPrefix)
//}

func (l *Lego) initLogger() {
	var lever zerolog.Level
	switch l.Engine.Config.LogLever {
	case "debug":
		lever = zerolog.DebugLevel
	case "info":
		lever = zerolog.InfoLevel
	case "error":
		lever = zerolog.ErrorLevel
	case "warn":
		lever = zerolog.WarnLevel
	case "trace":
		lever = zerolog.TraceLevel
	case "fatal":
		lever = zerolog.FatalLevel
	}
	zerolog.SetGlobalLevel(lever)
	sysLogger = zerolog.New(os.Stdout).With().CallerWithSkipFrameCount(3).Timestamp().Logger()
	l.Engine.SysLogger = sysLogger
	var err error
	filePath := getLogFilePath()
	fileName := getLogFileName()
	F, err = MustOpen(fileName, filePath)
	if err != nil {
		log.Fatalf("logging.Setup err: %v", err)
	}

	if app.Engine.Config.MultiLog {
		logger = zerolog.New(io.MultiWriter(F, os.Stdout)).
			With().Str("app", l.Engine.Config.AppName).CallerWithSkipFrameCount(3).Timestamp().Logger()
	} else {
		logger = zerolog.New(F).
			With().Str("app", l.Engine.Config.AppName).CallerWithSkipFrameCount(3).Timestamp().Logger()
	}
	l.Engine.AppLogger = logger

}

func SysInfof(format string, v ...interface{}) {
	sysLogger.Info().Msgf(format, v...)
}

func SysDebugf(format string, v ...interface{}) {
	sysLogger.Debug().Msgf(format, v...)
}

func SysErrorf(format string, v ...interface{}) {
	sysLogger.Error().Msgf(format, v...)
}

func SysFatalf(format string, v ...interface{}) {
	sysLogger.Fatal().Msgf(format, v...)
}

func SysInfo(msg string) {
	sysLogger.Info().Msg(msg)
}
